using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using GSync.GoogleSystem;
using System.Diagnostics;


namespace GSync
{
    class Config
    {
        private const String GCAL_NAME = "gcalName";
        private const String DEF_USER = "user";
        private const String GCAL_FEED = "gcalFedd";
        private const String DELETE_BEFORE = "deleteBefore";
        private const String MAX_RESULTS = "maxResults";
        private const String SAVE_CREDENTIAL = "credential";
        public const String ACL = "acl";
        public const String USER_NAME="mail";
        public const String SHOW_FILTER = "filterOn";
        public const String DAY_START_OFFSET = "dayStartOffset";
        public const String CONFIG_PATH = "SOFTWARE\\GSync\\Settings";
        
        private int maxResults = 25;
        private int dayStartOffSet;

        public int DayStartOffSet
        {
            get { return dayStartOffSet; }
            set { dayStartOffSet = value; }
        }
        private String query=null;
        private String textFilter = null;
        
        public String TextFilter
        {
            get { return textFilter; }
            set { textFilter = value; }
        }
        public String Query
        {
            get {
                if (query == null)
                {
                    return defaultQuery();
                }
                return query; }
            set { query = value; }
        }

        private Boolean showFilter = false;

        public Boolean ShowFilter
        {
            get { return showFilter; }
            set { showFilter = value; }
        }
        public int MaxResults
        {
            get { return maxResults; }
            set { maxResults = value; }
        }
        private Boolean saveCredential = false;

        public Boolean SaveCredential
        {
            get { return saveCredential; }
            set { saveCredential = value; }
        }
        private Credential credential;

        internal Credential Credential
        {
            get { return credential; }
            set { credential = value; }
        }
        private Boolean defaultDeleteBeforeImport = false;

        public Boolean DefaultDeleteBeforeImport
        {
            get { return defaultDeleteBeforeImport; }
            set { defaultDeleteBeforeImport = value; }
        }

        private String defaultGCalName = null;

        public String DefaultGCalName
        {
            get { return defaultGCalName; }
            set { defaultGCalName = value; }
        }

        private String defaultGCalFeedURI = null;

        public String DefaultGCalFeedURI
        {
            get { return defaultGCalFeedURI; }
            set { defaultGCalFeedURI = value; }
        }

        public GSItem getDefaultCalItem()
        {
            GSItem item = null;
            if (DefaultGCalName != null && DefaultGCalFeedURI!=null)
            {
                item = new GSItem();
                item.Id = DefaultGCalFeedURI;
                item.Title = DefaultGCalName;
            }
            return item;
        }

        public void setDefaultCal()
        {
            RegistryKey rootReg = Registry.CurrentUser.CreateSubKey(CONFIG_PATH);
            rootReg.SetValue(DEF_USER, this.Credential.UserName);
            String defUser = this.Credential.UserName.GetHashCode().ToString();
            RegistryKey reg = rootReg.CreateSubKey(defUser);
            if (DefaultGCalName != null && DefaultGCalFeedURI != null)
            {
                reg.SetValue(GCAL_NAME, this.DefaultGCalName);
                reg.SetValue(GCAL_FEED, this.DefaultGCalFeedURI);
            }
        }

        public void save()
        {
            RegistryKey rootReg = Registry.CurrentUser.CreateSubKey(CONFIG_PATH);
            rootReg.SetValue(DEF_USER, this.Credential.UserName);
            String defUser = this.Credential.UserName.GetHashCode().ToString();
            RegistryKey reg = rootReg.CreateSubKey(defUser);
            reg.SetValue(DELETE_BEFORE, this.DefaultDeleteBeforeImport);
            /*
            if (DefaultGCalName != null && DefaultGCalFeedURI!=null)
            {
                reg.SetValue(GCAL_NAME, this.DefaultGCalName);
                reg.SetValue(GCAL_FEED, this.DefaultGCalFeedURI);
            }
             */ 
            reg.SetValue(MAX_RESULTS, this.MaxResults);
            reg.SetValue(SAVE_CREDENTIAL, this.SaveCredential);
            if (saveCredential)
            {
                this.Credential.save(defUser);
            }
        }
        public static Config load()
        {
            return load(null);
        }


        public String defaultQuery()
        {
            String result = "orderby=starttime&" + (DayStartOffSet == 0 ? "futureevents=true" : "start-min=" + DateTime.Now.AddDays(DayStartOffSet).ToString("yyyy-MM-dd"));
            if (MaxResults != 25)
            {
                result += "&max-results=" + MaxResults;
            }
            return result;
        }

        public static Config load(Credential defaultCredential)
        {
            RegistryKey rootReg = Registry.CurrentUser.OpenSubKey(Config.CONFIG_PATH);
            Config option = new Config();
            String deUser = null;
            try
            {
                deUser = (String)rootReg.GetValue(DEF_USER);
                deUser = deUser.GetHashCode().ToString();
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.StackTrace);
                option.Credential = new Credential();
                return option;
            }
            try
            {
                if (rootReg.GetValue(SHOW_FILTER) != null)
                {
                    option.ShowFilter = Boolean.Parse((String)rootReg.GetValue(SHOW_FILTER));
                }
                if (rootReg.GetValue(DAY_START_OFFSET) != null)
                {
                    String dayStartOffSetS =(String) rootReg.GetValue(DAY_START_OFFSET);
                    if (dayStartOffSetS != null && dayStartOffSetS.Length > 0)
                    {
                        option.DayStartOffSet = int.Parse(dayStartOffSetS);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.StackTrace);
                option.ShowFilter = false;
            }
            RegistryKey reg = rootReg.OpenSubKey(deUser);
            
            try
            {
                String defaulName = (String)reg.GetValue(GCAL_NAME);
                option.defaultGCalName = defaulName;
                String defaultFeed = (String)reg.GetValue(GCAL_FEED);
                option.defaultGCalFeedURI = defaultFeed;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.StackTrace);
                option.defaultGCalName = null;                
            }
            try
            {
                int maxResults = (int)reg.GetValue(MAX_RESULTS);
                option.maxResults =maxResults;

            }
            catch (Exception e)
            {
                Debug.WriteLine(e.StackTrace);
                option.maxResults = 25;
            }
            try
            {
                Boolean defaultBehavior = Boolean.Parse((String)reg.GetValue(DELETE_BEFORE));
                option.defaultDeleteBeforeImport = defaultBehavior;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.StackTrace);
                option.defaultDeleteBeforeImport = false;
            }

            try
            {
                Boolean saveCred = Boolean.Parse((String)reg.GetValue(SAVE_CREDENTIAL));
                option.SaveCredential = saveCred;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.StackTrace);
                option.SaveCredential = false;
            }

            if (option.SaveCredential || defaultCredential == null)
            {
                Credential cred = Credential.load(deUser);
                option.credential = cred;
            }
            else
            {
                option.credential = defaultCredential;
            }
            return option;
        }
    }
}
